在[Day03]~[Day06],我們將使用下面這個schema幫助我們熟悉EdgeDB的基本操作。
type User {
    required name: str;
    multi followers: User;
}
type Article {
    required title: str;
    required author: User;
}
這個schema內定義了:
User object type
property,且為required及 single,即每次insert時都要提供一個str型態。link,且為optional及multi,即每次insert時不一定要提供;但如果有提供的話,可以包含一個以上的User object。Article object type
property,且為required及single,即每次insert時都要提供一個str型態。link,且為required及single,即每次insert時都要提供一個User object。insert可以幫助我們建立object。在EdgeDB中關鍵字是case insensitive,所以insert與InSeRt會被視為是相同的。在傳統SQL中,很多人都習慣將關鍵字大寫,但在EdgeQL的官方文件中,關鍵字皆以小寫呈現。我自己是習慣寫成小寫,但大家可以依照自己的喜好來選擇,我相信只要寫法是一致的,閱讀起來應該都不會太困難。
以下我將以Cathy、John、Tom與Jeff來簡單稱呼其name property分別為「"Cathy"」、「"John"」、「"Tom"」與「"Jeff"」的User object。
假設我們想建立John,可以使用insert搭配shape(即{})來做:
insert User {name:= "John"};
這邊有兩點需要注意:
property或link時需使用:=。;作為結束。接著我們建立一個Article object,其title property為「"first article"」,author link為John:
insert Article {
     title:= "first article",
     author:= assert_single(User)
};
目前我們只有John一個User object,所以我們可以「取巧」以User代替,而不必真的選取到John。由於author是single link,所以必須使用assert_single()來確定其返回結果不會多於一個(如果沒有使用assert_single()或返回結果多於一個的話,都會報錯)。assert_single()是一個funtion,可以說是EdgeDB最常使用的保護措施之一,剛開始可能會覺得不太習慣,但這就像是另類的型別檢查一樣,雖然一開始要多花點功夫,但卻可以避免後面可能生的一連串錯誤。
由於像上述這樣的情況相當常見,我們一般會使用下面這種query:
insert Article {
   title:= "first article",
   author:= (insert User {name:= "John"})
};
由於insert的返回結果必定是一個或以下,所以這邊可以不用加上assert_single()。但如果改寫為下面這樣,也是正確的寫法:
insert Article {
   title:= "first article",
   author:= assert_single((insert User {name:= "John"}))
};
請注意assert_single()內需要使用括號,不可省略。如果寫成下面這樣:
❌
insert Article {
   title:= "first article",
   author:= assert_single(insert User {name:= "John"})
};
EdgeDB會報錯:
error: EdgeQLSyntaxError: Missing parentheses around statement used as an expression
Bulk inserts是使用for-loop來同時生成大量的object。例如,我們想同時生成Jeff、Tom及Cathy的話,可以這麼寫:
for name in {"Jeff", "Tom", "Cathy"}
union (insert User {name:= name});
其中union為EdgeDB連接兩個EdgeDBSet的運算子。
值得一提的是,在EdgeDBv5之後,union變成可省略的關鍵字,也就是說上述query也可以寫成:
for name in {"Jeff", "Tom", "Cathy"}
insert User {name:= name};
如果將union寫出來,可以更加表現出所有的query結果都是EdgeDBSet;但是省略union的確可以讓語法更簡潔,也更像一般程式中的for-loop,大家可以自己選擇喜歡的寫法。